package com.tg.data.helper;

import android.content.Context;

import androidx.annotation.NonNull;

import com.tg.appcommon.android.AlarmUtil;
import com.tange.base.toolkit.FileUtil;
import com.tg.appcommon.android.Packet;
import com.tange.base.toolkit.StringUtils;
import com.tg.appcommon.android.TGLog;
import com.tange.base.toolkit.TGThreadPool;
import com.tg.data.http.entity.AlarmToneCapBean;
import com.tg.data.http.entity.DeviceBellBean;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class SoundHelper {
    public static final String TAG = TGLog.TAG;
    public static final int MAX_CUSTOM = 5;
    public static final String wavFileTemp = "temp.wav";
    public static final String FORMAT_WAV_SUFFIX= ".wav";
    public static final String SPLIT_CHAR = "_";
    public final List<DeviceBellBean> mList = new ArrayList<>();
    public final List<DeviceBellBean> mCloudList = new ArrayList<>();


    public String mDirectory;

    public String mSelectAlarmTone;

    public String mIdAlarmTone;
    public boolean mExist = false;

    public AlarmToneCapBean alarmToneCapBean;

    public void setAlarmToneCapBean(AlarmToneCapBean bean){
        if (bean != null){
            alarmToneCapBean = bean;
        }
    }

    public AlarmToneCapBean getAlarmToneCapBean(){
        return alarmToneCapBean;
    }

    public int getAudioCodecs() {
        return alarmToneCapBean.audioCodecs;
    }

    public String getSelectAlarmTone() {
        return mSelectAlarmTone;
    }

    public void setSelectAlarmTone(@NonNull String selectAlarmTone) {
        mSelectAlarmTone = selectAlarmTone;
    }

    public String getVoiceFileDir(@NonNull Context context) {
        return FileUtil.getDiskFileDir(context);
    }

    public DeviceBellBean getCustomDeviceBellBean() {
        return null;
    }

    public boolean deleteNoExistFile(@NonNull String idAlarmTone) {
        return true;
    }
    public String getShowText() {
        return null;
    }
    public void setCloudList(@NonNull List<DeviceBellBean> list){
        mCloudList.clear();
        mCloudList.addAll(list);
    }


    public boolean exist(){
        return true;
    }

    public void setIdAlarmTone(@NonNull String idAlarmTone, String label) {
        mIdAlarmTone = idAlarmTone;
        mExist = exist();
        if (!mExist) {
            DeviceBellBean deviceBellBean = new DeviceBellBean(mIdAlarmTone, label);
            mCloudList.add(deviceBellBean);
        }
    }


    @NonNull
    public File getTempFile(Context context) {
        return FileUtil.getDiskFileDir(context, wavFileTemp);
    }

    public boolean isCustomExceed(){
        return mList.size() >= MAX_CUSTOM;
    }

    @NonNull
    public String getDirectory() {
        return mDirectory;
    }

    @NonNull
    public String getFilePath(@NonNull String name) {
        String path = mDirectory + File.separator + name + FORMAT_WAV_SUFFIX;
        TGLog.d("path = " + path);
        return path;
    }

    public void setWaveFileHeader(@NonNull File file) {
        AlarmUtil.setWaveFileHeader(file, alarmToneCapBean.mBitsPerSample, alarmToneCapBean.audioCodecs, alarmToneCapBean.mSamplePerSecs, alarmToneCapBean.mChannels);
    }

    public static int getVoiceFileId(String path, long time) {
        try {
            File file = new File(path);
            if (file.exists()){
                FileInputStream is = new FileInputStream(file.getPath());
                byte[] data =  FileUtil.readStreamAsBytesArray(is, time);
                MessageDigest digest = java.security.MessageDigest.getInstance("MD5");
                digest.update(data);
                byte[] messageDigest = digest.digest();
                byte[] result = new byte[4];
                result[3] = (byte)0x80;
                result[2] = messageDigest[messageDigest.length-3];
                result[1] = messageDigest[messageDigest.length-2];
                result[0] = messageDigest[messageDigest.length-1];
                int ret = Packet.byteArrayToInt_Little(result, 0);
                TGLog.d("ret = " + ret + ", path = " + path);
                return ret;
            }

        } catch (NoSuchAlgorithmException | FileNotFoundException e) {
            TGLog.d("NoSuchAlgorithmException | FileNotFoundException");
            e.printStackTrace();
        } catch (IOException e) {
            TGLog.d("IOException");
            e.printStackTrace();
        }
        TGLog.d("file is no exist");
        return -1;
    }

    public void addFile(@NonNull String name){
        String[] tmp = name.split(SPLIT_CHAR);
        if (tmp.length == 3 && StringUtils.isNumeric(tmp[0]) && StringUtils.isNumeric(tmp[1])){
            DeviceBellBean deviceBellBean = new DeviceBellBean();
            deviceBellBean.setDescription(tmp[2]);
            deviceBellBean.setName(name);
            deviceBellBean.setFlag(Integer.parseInt(tmp[1]));
            String path = getFilePath(name);
            int id = getVoiceFileId(path, Long.parseLong(tmp[0]));
            TGLog.d("id = " + id);
            deviceBellBean.setId(Integer.toString(id));
            mList.add(deviceBellBean);
        }
    }

    @NonNull
    public List<DeviceBellBean> getAllList() {
        List<DeviceBellBean> list = new ArrayList<>(mCloudList);
        for (DeviceBellBean deviceBellBean : mList) {
            TGLog.d("bean.id = " + deviceBellBean.getId());
            if (deviceBellBean.getId().equals("-1")) {
                String path = getFilePath(deviceBellBean.getName());
                String[] tmp = deviceBellBean.getName().split(SPLIT_CHAR);
                TGLog.d("getAllList path = " + path);
                int id = getVoiceFileId(path, Long.parseLong(tmp[0]));
                TGLog.d("getAllList id = " + id);
                if (id != -1) {
                    deviceBellBean.setId(Integer.toString(id));
                }
            }
        }
        list.addAll(mList);
        return list;
    }

    public boolean delete(@NonNull DeviceBellBean deviceBellBean) {
        String path = getFilePath(deviceBellBean.getName());
        boolean ret = FileUtil.deleteFile(path, false);
        if (ret) {
            mList.remove(deviceBellBean);
        }
        return ret;
    }

    public void findVoiceFile(@NonNull Context context, @NonNull String uuid) {
        mDirectory = getVoiceFileDir(context) + File.separator + uuid;
        if(!FileUtil.isFolderExists(mDirectory)){
            if (!FileUtil.createFolder(mDirectory)){
                String fileDir = getVoiceFileDir(context);
                if (!FileUtil.isFolderExists(fileDir)){
                    FileUtil.createFolder(fileDir);
                    FileUtil.createFolder(mDirectory);
                }
            }
        }

        TGThreadPool.execute(() -> {
            List<String> list = FileUtil.findAllFile(mDirectory);
            mList.clear();
            for (String name : list) {
                TGLog.d(TAG, "filename = " + name);
                if (!StringUtils.isEmpty(name) && !name.startsWith(uuid) && name.endsWith(FORMAT_WAV_SUFFIX)) {
                    String tmpName = name.replace(FORMAT_WAV_SUFFIX, "");
                    addFile(tmpName);
                }
            }
            Collections.sort(mList, (d1, d2) -> d1.getName().compareTo(d2.getName()));
        });
    }

    private boolean find(String description){
        for (DeviceBellBean deviceBellBean : mList){
            if (deviceBellBean.isPersonal() && deviceBellBean.getDescription().equals(description)){
                return true;
            }
        }
        return false;
    }

    public String getNextPersonalFileDescription(String desc){
        String str = desc;
        for (int i = 1; i <= MAX_CUSTOM ; i++){
            String description = str + i;
            if (!find(description)) {
                return description;
            }
        }
        return null;
    }

}
